/**
 * KioskMediator is responsible for updating the loading screen while the
 * application loads data, pre-loads images and pre-renders the coverflow
 * list items.
 * 
 * It is also responsible for dispatching the brochure pre-render
 * events during the application pre-rendering stage and for hiding the loading
 * screen once pre-rendering is complete.
 * 
 * It is also responsible for dispatching notifications of any user interaction
 * with the application or when the application is idling or switching between
 * the home and content view states.
 * 
 * @author		Scott Steven Rodriguez
 * @link 		http://www.flashsherpa.com
 */
package com.ettractions.kiosk.mediators
{
	import com.ettractions.kiosk.Kiosk;
	import com.ettractions.kiosk.components.LoadingScreen;
	import com.ettractions.kiosk.events.BrochureSelectedEvent;
	import com.ettractions.kiosk.events.ImagePreloadServiceEvent;
	import com.ettractions.kiosk.events.KioskDataServiceEvent;
	import com.ettractions.kiosk.events.KioskModelEvent;
	import com.ettractions.kiosk.events.PreRenderBrochureEvent;
	import com.ettractions.kiosk.events.SelectBrochureEvent;
	import com.ettractions.kiosk.events.ViewStateEvent;
	import com.ettractions.kiosk.models.KioskModel;
	import com.ettractions.kiosk.vo.BrochureVO;
	
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import org.robotlegs.mvcs.Mediator;
	
	public class KioskMediator extends Mediator
	{
		/**
		 * Interval (in milliseconds) between brochure pre-render event dispatches
		 */
		private static const PRE_RENDER_INTERVAL:uint = 5;
		
		/**
		 * Maximum amount of time (in milliseconds) application is allowed
		 * to remain idle before returning to screen saver view
		 */
		private static const MAX_IDLE_TIME:uint = 30000;
		
		[Inject]
		public var view:Kiosk;
		
		[Inject]
		public var model:KioskModel;
		
		private var _preRenderTimer:Timer = new Timer(PRE_RENDER_INTERVAL);
		
		private var _preRenderBrochureIndex:uint = 0;
		
		private var _idleTimer:Timer = new Timer(MAX_IDLE_TIME, 1);
		
		private var _currentBrochure:BrochureVO = null;
		
		override public function onRegister():void
		{
			eventDispatcher.addEventListener(KioskDataServiceEvent.LOAD_KIOSK_DATA, handleLoadKioskData);
			eventDispatcher.addEventListener(KioskDataServiceEvent.KIOSK_DATA_FILE_LOADED, handleKioskDataFileLoaded);
			eventDispatcher.addEventListener(KioskDataServiceEvent.ASSETS_DATA_FILE_LOADED, handleAssetsDataFileLoaded);
			eventDispatcher.addEventListener(KioskDataServiceEvent.KIOSK_DATA_LOADED, handleKioskDataLoaded);
			eventDispatcher.addEventListener(KioskModelEvent.UPDATED, handleKioskModelUpdated);
			eventDispatcher.addEventListener(ImagePreloadServiceEvent.PRELOAD_IMAGES, handlePreloadImages);
			eventDispatcher.addEventListener(ImagePreloadServiceEvent.IMAGES_PRELOADED, handleImagesPreloaded);
			eventDispatcher.addEventListener(ViewStateEvent.USER_INTERACTION, handleUserInteraction);
			eventDispatcher.addEventListener(BrochureSelectedEvent.BROCHURE_SELECTED, handleBrochureSelected);
			
			view.stage.addEventListener(MouseEvent.MOUSE_DOWN, handleStageMouseDown);

			_preRenderTimer.addEventListener(TimerEvent.TIMER, handlePreRenderTimer);
			
			_idleTimer.addEventListener(TimerEvent.TIMER_COMPLETE, handleIdleTimerComplete);
		}
		
		private function handleLoadKioskData(event:KioskDataServiceEvent):void
		{
			eventDispatcher.removeEventListener(KioskDataServiceEvent.LOAD_KIOSK_DATA, handleLoadKioskData);
			
			LoadingScreen.instance.appendText("Loading data...\n");
		}		
		
		private function handleKioskDataFileLoaded(event:KioskDataServiceEvent):void
		{
			eventDispatcher.removeEventListener(KioskDataServiceEvent.KIOSK_DATA_FILE_LOADED, handleKioskDataFileLoaded);

			LoadingScreen.instance.appendText("\tKiosk data file loaded...\n");
		}
		
		private function handleAssetsDataFileLoaded(event:KioskDataServiceEvent):void
		{
			eventDispatcher.removeEventListener(KioskDataServiceEvent.ASSETS_DATA_FILE_LOADED, handleAssetsDataFileLoaded);
			
			LoadingScreen.instance.appendText("\tAssets data file loaded...\n");
		}
		
		private function handleKioskDataLoaded(event:KioskDataServiceEvent):void
		{
			eventDispatcher.removeEventListener(KioskDataServiceEvent.KIOSK_DATA_LOADED, handleKioskDataLoaded);
			
			LoadingScreen.instance.appendText("Data loaded...\n");
		}
		
		private function handleKioskModelUpdated(event:KioskModelEvent):void
		{
			eventDispatcher.removeEventListener(KioskModelEvent.UPDATED, handleKioskModelUpdated);
			
			LoadingScreen.instance.appendText("Kiosk model updated...\n");
		}
		
		private function handlePreloadImages(event:ImagePreloadServiceEvent):void
		{
			eventDispatcher.removeEventListener(ImagePreloadServiceEvent.PRELOAD_IMAGES, handlePreloadImages);
			
			LoadingScreen.instance.appendText("Pre-loading... ");
		}
		
		private function handleImagesPreloaded(event:ImagePreloadServiceEvent):void
		{
			eventDispatcher.removeEventListener(ImagePreloadServiceEvent.IMAGES_PRELOADED, handleImagesPreloaded);
			
			LoadingScreen.instance.appendText("done.\n");
			LoadingScreen.instance.appendText("Pre-rendering... ");
			
			eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.PRE_RENDERING));
			
			_preRenderTimer.start();
			
			eventDispatcher.dispatchEvent(new PreRenderBrochureEvent(PreRenderBrochureEvent.PRE_RENDER_BROCHURE, model.condensedBrochures[_preRenderBrochureIndex]));
		}
		
		private function handlePreRenderTimer(event:TimerEvent):void
		{
			if (++_preRenderBrochureIndex == model.condensedBrochures.length)
			{
				_preRenderTimer.stop();
				_preRenderTimer.removeEventListener(TimerEvent.TIMER, handlePreRenderTimer);	
				_preRenderTimer = null;
				
				LoadingScreen.instance.parent.removeChild(LoadingScreen.instance);
				LoadingScreen.instance = null;

				eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.PRE_RENDERING_COMPLETE));
				eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.IDLING));				
			}
			
			else
				eventDispatcher.dispatchEvent(new PreRenderBrochureEvent(PreRenderBrochureEvent.PRE_RENDER_BROCHURE, model.condensedBrochures[_preRenderBrochureIndex]));
		}
		
		private function handleUserInteraction(event:ViewStateEvent):void
		{
			_idleTimer.reset();
			_idleTimer.start();
		}
		
		private function handleBrochureSelected(event:BrochureSelectedEvent):void
		{
			_currentBrochure = event.brochure;
		}

		private function handleStageMouseDown(event:MouseEvent):void
		{
			view.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleStageMouseMove);
			view.stage.addEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
			
			eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.USER_INTERACTION));
		}
		
		private function handleStageMouseMove(event:MouseEvent):void
		{
			eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.USER_INTERACTION));
		}
		
		private function handleStageMouseUp(event:MouseEvent):void
		{
			view.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleStageMouseMove);
			view.stage.removeEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
			
			eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.USER_INTERACTION));
		}
		
		private function handleIdleTimerComplete(event:TimerEvent):void
		{
			eventDispatcher.dispatchEvent(new ViewStateEvent(ViewStateEvent.IDLING));
			
			if (_currentBrochure != null)
				eventDispatcher.dispatchEvent(new SelectBrochureEvent(SelectBrochureEvent.SELECT_BROCHURE, null));
		}
	}
}